home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 1.toast / pc / sample code / graphics 2d / snapshot / snapshot.c next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  6.8 KB  |  238 lines

  1. /*
  2.     File:        Snapshot.c
  3.  
  4.     Contains:    This application demonstrates how to quickly and        
  5.                 efficiently capture the main device's desktop into            
  6.                 a window.  The program basically reads the image             
  7.                 stored in the the main device's pixmap then copies            
  8.                 it to a custom pixmap.  The custom pixmap is de-            
  9.                 fined at the same depth of the main device and                 
  10.                 contains an identical copy of that device's color-            
  11.                 table.  This is done to provide the fastest                 
  12.                 performance possible when copying from an offscreen            
  13.                 to onscreen pixmap.  By making sure the pixel values        
  14.                 map to the exact same colors in both colortables,            
  15.                 copybits will do a direct transfer of bits without            
  16.                 wasting time remapping the colors.  Also the ctSeed            
  17.                 field for each colortable should be the same.  Finally,        
  18.                 since the main device's bounding rect is different            
  19.                 than that of the offscreen's, the copying performance        
  20.                 for the device to the offscreen is slightly affected        
  21.                 because of the scaling required.  However, the copying        
  22.                 performance for the offscreen to the window is the             
  23.                 best possible since the bounding rects for each are            
  24.                 identical.                                        
  25.  
  26.     Written by: Edgar Lee    
  27.  
  28.     Copyright:    Copyright © 1991-1999 by Apple Computer, Inc., All Rights Reserved.
  29.  
  30.                 You may incorporate this Apple sample source code into your program(s) without
  31.                 restriction. This Apple sample source code has been provided "AS IS" and the
  32.                 responsibility for its operation is yours. You are not permitted to redistribute
  33.                 this Apple sample source code as "Apple sample source code" after having made
  34.                 changes. If you're going to re-distribute the source, we require that you make
  35.                 it clear in the source that the code was descended from Apple sample source
  36.                 code, but that you've made changes.
  37.  
  38.     Change History (most recent first):
  39.                 7/14/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  40.                 
  41.                 11/6/1999    Geoff Stahl     Updated to work with modern (1999) Mac OS.  
  42.                                             Fixed a PixMap disposing bug.  Updated casts
  43.                                             and headers.
  44.  
  45.  
  46.                 
  47.  
  48. */
  49.  
  50. #include <AppleEvents.h>
  51. #include <Errors.h>
  52. #include <Events.h>
  53. #include <Fonts.h>
  54. #include <Gestalt.h>
  55. #include <Memory.h>
  56. #include <Menus.h>
  57. #include <OSUtils.h>
  58. #include <QDOffscreen.h>
  59. #include <QuickDraw.h>
  60. #include <Resources.h>
  61. #include <Script.h>
  62. #include <ToolUtils.h>
  63. #include <Windows.h>
  64. #include <TextEdit.h>
  65. #include <Dialogs.h>
  66.  
  67. /* Constant Declarations */
  68.  
  69. #define    WWIDTH        ((qd.screenBits.bounds.right - qd.screenBits.bounds.left) / 2)
  70. #define    WHEIGHT        ((qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) / 2)
  71.  
  72. #define WLEFT        (((qd.screenBits.bounds.right - qd.screenBits.bounds.left) - WWIDTH) / 2)
  73. #define WTOP        (((qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) - WHEIGHT) / 2)
  74.  
  75. /* Global Variable Definitions */
  76.  
  77. WindowPtr    gWindow;            /* Main window */
  78. PixMap        gPixMap;            /* Offscreen pixmap */
  79. Rect        gBounds;            /* Offscreen pixmap's bounding rect */
  80.  
  81. void initMac();
  82.  
  83. void createWindow();
  84.  
  85. void initPixmap();
  86. void createImage();
  87. void drawImage();
  88.  
  89. void doEventLoop();
  90.  
  91. void main()
  92. {
  93.     initMac();
  94.     
  95.     createWindow();                /* Create a window to display the final image. */
  96.     
  97.     initPixmap();                /* Initialize offscreen pixmap. */
  98.     createImage();                /* Copy the main screen's pixmap into the offscreen's. */
  99.     drawImage();                /* Copy the offscreen's pixmap onto the window. */
  100.  
  101.     doEventLoop();                /* Handle any events. */
  102.     
  103.     DisposeWindow( gWindow );
  104. }
  105.  
  106. void initMac()
  107. {
  108.     MaxApplZone();
  109.     
  110.     InitGraf( &qd.thePort );
  111.     InitFonts();
  112.     InitWindows();
  113.     InitMenus();
  114.     TEInit();
  115.     InitDialogs( nil );
  116.     InitCursor();
  117.     FlushEvents( 0, everyEvent );    
  118. }
  119.  
  120. void createWindow()
  121. {
  122.     Rect wBounds;
  123.     
  124.     /* Create a window to display the final offscreen image. */
  125.     
  126.     SetRect( &wBounds, WLEFT, WTOP, WLEFT + WWIDTH, WTOP + WHEIGHT );
  127.     
  128.     gWindow = NewCWindow( 0L, &wBounds, "\pSnapshot Test", false, documentProc,
  129.                             (WindowPtr)-1L, true, 0L );
  130.                             
  131.     SetRect( &gBounds, 0, 0, gWindow->portRect.right - gWindow->portRect.left,
  132.                     gWindow->portRect.bottom - gWindow->portRect.top );
  133.                             
  134.     SetPort( gWindow );
  135. }
  136.  
  137. void initPixmap()
  138. {
  139.     Ptr            offBaseAddr;    /* Pointer to the off-screen pixel image */
  140.     short        bytesPerRow;
  141.     GDHandle    mainDevice;
  142.     CTabHandle    cTable;
  143.     short        depth;
  144.  
  145.     /* Get a handle to the main device. */
  146.     mainDevice = GetMainDevice();
  147.  
  148.     /* Store its current pixel depth. */
  149.     depth = (**(**mainDevice).gdPMap).pixelSize;
  150.  
  151.     /* Make an identical copy of its pixmap's colortable. */
  152.     cTable = (**(**mainDevice).gdPMap).pmTable;
  153.     HandToHand( &(Handle)cTable );
  154.  
  155.     bytesPerRow = ((gBounds.right - gBounds.left) * depth) / 8;
  156.     offBaseAddr = NewPtr((unsigned long)bytesPerRow * (gBounds.bottom - gBounds.top));
  157.     
  158.     gPixMap.baseAddr = offBaseAddr;              /* Point to image */
  159.     gPixMap.rowBytes = bytesPerRow | 0x8000;    /* MSB set for PixMap */
  160.     gPixMap.bounds = gBounds;                     /* Use given bounds */
  161.     gPixMap.pmVersion = 0;                       /* No special stuff */
  162.     gPixMap.packType = 0;                        /* Default PICT pack */
  163.     gPixMap.packSize = 0;                        /* Always zero in mem */
  164.     gPixMap.hRes = 72;                          /* 72 DPI default res */
  165.     gPixMap.vRes = 72;                          /* 72 DPI default res */
  166.     gPixMap.pixelSize = depth;                   /* Set # bits/pixel */
  167.     gPixMap.planeBytes = 0;                      /* Not used */
  168.     gPixMap.pmReserved = 0;                      /* Not used */
  169.  
  170.     gPixMap.pixelType = 0;                       /* Indicates indexed */
  171.     gPixMap.cmpCount = 1;                        /* Have 1 component */
  172.     gPixMap.cmpSize = depth;                     /* Component size=depth */
  173.     gPixMap.pmTable = cTable;                     /* Handle to CLUT */
  174. }
  175.  
  176. void createImage()
  177. {
  178.     GDHandle    mainDevice;
  179.  
  180.     mainDevice = GetMainDevice();
  181.  
  182.     /* Store the screen's pixmap image in the offscreen pixmap. */
  183.  
  184.     CopyBits( (BitMap *)*(**mainDevice).gdPMap, (BitMap *)(&gPixMap),
  185.                 &(**(**mainDevice).gdPMap).bounds, &gPixMap.bounds, srcCopy, 0l );
  186. }
  187.  
  188. void drawImage()
  189. {
  190.     /* Copy the offscreen image back onto the window. */
  191.  
  192.     CopyBits( (BitMap *)&gPixMap, &gWindow->portBits, &gPixMap.bounds,
  193.                 &gWindow->portRect, srcCopy, 0l);
  194.                 
  195.     ShowWindow( gWindow );
  196. }
  197.  
  198. void doEventLoop()
  199. {
  200.     EventRecord anEvent;
  201.     WindowPtr   evtWind;
  202.     short       clickArea;
  203.     Rect        screenRect;
  204.  
  205.     for (;;)
  206.     {
  207.         if (WaitNextEvent( everyEvent, &anEvent, 0, nil ))
  208.         {
  209.             if (anEvent.what == mouseDown)
  210.             {
  211.                 clickArea = FindWindow( anEvent.where, &evtWind );
  212.                 
  213.                 if (clickArea == inDrag)
  214.                 {
  215.                     screenRect = (**GetGrayRgn ()).rgnBBox;
  216.                     DragWindow( evtWind, anEvent.where, &screenRect );
  217.                 }
  218.                 else if (clickArea == inContent)
  219.                 {
  220.                     if (evtWind != FrontWindow())
  221.                         SelectWindow( evtWind );
  222.                 }
  223.                 else if (clickArea == inGoAway)
  224.                     if (TrackGoAway( evtWind, anEvent.where ))
  225.                         return;
  226.             }
  227.             else if (anEvent.what == updateEvt)
  228.             {
  229.                 evtWind = (WindowPtr)anEvent.message;    
  230.                 SetPort( evtWind );
  231.                 
  232.                 BeginUpdate( evtWind );
  233.                 drawImage();
  234.                 EndUpdate (evtWind);
  235.             }
  236.         }
  237.     }
  238. }